package main

import (
	"time"
)

type ChannelLock struct {
	c chan struct{}
}

func NewChannelLock() *ChannelLock {
	return &ChannelLock{c: make(chan struct{}, 1)}
}

func (cl *ChannelLock) CLock(d time.Duration) bool {
	t := time.NewTimer(d)
	select {
	case cl.c <- struct{}{}:
		t.Stop()
		return true
	case <-t.C:
		return false
	}
}

func (cl *ChannelLock) CUnlock() {
	<-cl.c
}

func add(count *int, lock *ChannelLock) {
	lock.CLock(1000)
	*count++
	lock.CUnlock()
}

func main() {
	lock := NewChannelLock()
	count := 0
	for i := 0; i < 10000; i++ {
		go add(&count, lock)
	}

	time.Sleep(time.Second * 2)
	println(count)
}
